package br.com.puc.models;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.FetchType;

import br.com.puc.models.enums.StatusProjeto;
@javax.persistence.Entity
public class Projeto extends Entity {

	private String titulo;
	private String objetivo;
	private String descricao;
	private StatusProjeto status;
	private Date dataInicio;
	private Date dataTermino;
	private String agenciaFinanciadora;
	private int valorFinanciado;
	@javax.persistence.ManyToMany(targetEntity = Colaborador.class, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
	private List<Colaborador> participantes = new ArrayList<Colaborador>();
	@javax.persistence.OneToMany(mappedBy = "projeto", targetEntity = Publicacao.class, fetch = FetchType.EAGER)
	private List<Publicacao> publicacoes = new ArrayList<Publicacao>();
	
	public Projeto() {
		setStatus(StatusProjeto.EM_ELABORACAO);
	}

	public void setTitulo(String titulo) {
		this.titulo = titulo;
	}

	public String getTitulo() {
		return titulo;
	}

	public void setObjetivo(String objetivo) {
		this.objetivo = objetivo;
	}

	public String getObjetivo() {
		return objetivo;
	}

	public void setDescricao(String descricao) {
		this.descricao = descricao;
	}

	public String getDescricao() {
		return descricao;
	}

	public void setStatus(StatusProjeto status) {
		this.status = status;
	}

	public StatusProjeto getStatus() {
		return status;
	}

	public void setDataInicio(Date dataInicio) {
		this.dataInicio = dataInicio;
	}

	public Date getDataInicio() {
		return dataInicio;
	}
	
	public String getDataInicioStr() {
		if (getDataInicio() == null)
			return "";
		return new SimpleDateFormat("dd/MM/yyyy").format(getDataInicio());
	}

	public void setDataTermino(Date dataTermino) {
		this.dataTermino = dataTermino;
	}

	public Date getDataTermino() {
		return dataTermino;
	}
	
	public String getDataTerminoStr() {
		if (getDataTermino() == null)
			return "";
		return new SimpleDateFormat("dd/MM/yyyy").format(getDataTermino());
	}

	public String getAgenciaFinanciadora() {
		return agenciaFinanciadora;
	}

	public void setAgenciaFinanciadora(String agenciaFinanciadora) {
		this.agenciaFinanciadora = agenciaFinanciadora;
	}

	public int getValorFinanciado() {
		return valorFinanciado;
	}

	public void setValorFinanciado(int valorFinanciado) {
		this.valorFinanciado = valorFinanciado;
	}

	public List<Colaborador> getParticipantes() {
		return participantes;
	}

	public void setParticipantes(List<Colaborador> participantes) {
		this.participantes = participantes;
	}

	public List<Colaborador> getParticiantesInvalidos() {
		List<Colaborador> invalidos = new ArrayList<Colaborador>();
		for (Colaborador participante : getParticipantes()) {
			int atual = participante.getProjetosEmAndamento().contains(this) ? 1 : 0;
			if (participante.getTipoColaborador().equals("GRAD") && participante.getProjetosEmAndamento().size() - atual >= 2)
				invalidos.add(participante);
		}
		return invalidos;
	}

	public boolean podeSerIniciado() {
		return (getStatus() == StatusProjeto.EM_ELABORACAO 
				&& existeProfessorNoProjeto()
				&& dadosBasicosEstaoPreenchidos()
				&& (getParticiantesInvalidos().size()==0));
	}

	private boolean dadosBasicosEstaoPreenchidos() {
		boolean tituloPreenchido = campoPreenchido(getTitulo());
		boolean agenciaPreenchida = campoPreenchido(getAgenciaFinanciadora());
		boolean objetivoPreenchido = campoPreenchido(getObjetivo());
		boolean descricaoPreenchida = campoPreenchido(getDescricao());
		boolean dataInicioPreenchida = getDataInicio() != null;
		boolean dataTerminoPreenchida = getDataTermino() != null;
		
		return tituloPreenchido && agenciaPreenchida && objetivoPreenchido 
				&& descricaoPreenchida && dataInicioPreenchida && dataTerminoPreenchida;
	}

	private boolean campoPreenchido(String campo) {
		return campo != null && campo.length() > 0;
	}

	private boolean existeProfessorNoProjeto() {
		for (Colaborador colaborador : getParticipantes()) {
			if (colaborador.getTipoColaborador().equals("PROF"))
				return true;
		}
		return false;
	}

	public boolean podeSerConcluido() {
		return getStatus() == StatusProjeto.EM_ANDAMENTO
				&& getPublicacoes() != null && getPublicacoes().size() > 0;
	}
	
	public List<Publicacao> getPublicacoesPorData() {
		Collections.sort(publicacoes, new Comparator<Publicacao>() {
			@Override public int compare(Publicacao o1, Publicacao o2) {
				if (o1.getAno() > o2.getAno())
					return -1;
				if (o1.getAno() == o2.getAno())
					return 0;
				return 1;
		}});
		return publicacoes;
	}

	public List<Publicacao> getPublicacoes() {
		return publicacoes;
	}

	public void setPublicacoes(List<Publicacao> publicacoes) {
		this.publicacoes = publicacoes;
	}
}